-
-
Notifications
You must be signed in to change notification settings - Fork 37
♻️ Replace pybind11 with nanobind
#766
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
📝 WalkthroughSummary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings. WalkthroughMigrates Python bindings from pybind11 to nanobind, updates build/config to produce Stable ABI wheels for Python 3.12+, bumps MQT Core dependency to 3.4.0, updates CI and tooling to use nanobind, and removes pybind11-specific config entries. Changes
Sequence Diagram(s)sequenceDiagram
participant CI as CI workflow
participant CMake as CMake / Build
participant Nanobind as nanobind pkg
participant Python as Python runtime
CI->>CMake: run build (install nanobind in env)
CMake->>Nanobind: execute_process to locate nanobind
CMake->>CMake: find_package(nanobind CONFIG REQUIRED)
CMake->>CMake: configure & build bindings (use nb APIs)
CMake->>Python: produce wheel (abi3/cp312 support)
Python->>Nanobind: import nanobind internals at runtime
Python->>CI: run tests against built module
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
📜 Recent review detailsConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro 📒 Files selected for processing (3)
🧰 Additional context used🧠 Learnings (20)📓 Common learnings📚 Learning: 2025-12-22T01:25:21.609ZApplied to files:
📚 Learning: 2025-12-15T01:54:22.129ZApplied to files:
📚 Learning: 2025-12-21T22:35:08.572ZApplied to files:
📚 Learning: 2025-12-15T01:59:17.023ZApplied to files:
📚 Learning: 2025-12-07T01:21:27.544ZApplied to files:
📚 Learning: 2025-12-19T00:05:54.428ZApplied to files:
📚 Learning: 2026-01-04T23:01:47.734ZApplied to files:
📚 Learning: 2026-01-09T17:58:10.350ZApplied to files:
📚 Learning: 2025-12-13T20:08:45.549ZApplied to files:
📚 Learning: 2025-10-10T08:09:54.528ZApplied to files:
📚 Learning: 2025-10-10T08:10:16.394ZApplied to files:
📚 Learning: 2025-12-28T17:13:36.900ZApplied to files:
📚 Learning: 2025-10-09T22:15:59.924ZApplied to files:
📚 Learning: 2026-01-04T23:54:33.540ZApplied to files:
📚 Learning: 2025-12-05T17:45:37.602ZApplied to files:
📚 Learning: 2025-11-04T15:22:19.558ZApplied to files:
📚 Learning: 2025-12-14T16:51:52.504ZApplied to files:
📚 Learning: 2025-11-04T14:26:25.420ZApplied to files:
📚 Learning: 2025-10-11T19:39:32.050ZApplied to files:
🧬 Code graph analysis (1)bindings/bindings.cpp (1)
🪛 Cppcheck (2.19.0)bindings/bindings.cpp[information] 23-23: Include file (missingIncludeSystem) [information] 24-24: Include file (missingIncludeSystem) [information] 25-25: Include file (missingIncludeSystem) [information] 26-26: Include file (missingIncludeSystem) [information] 27-27: Include file (missingIncludeSystem) [information] 28-28: Include file (missingIncludeSystem) [information] 29-29: Include file (missingIncludeSystem) [information] 30-30: Include file (missingIncludeSystem) [information] 31-31: Include file (missingIncludeSystem) [information] 32-32: Include file (missingIncludeSystem) [information] 33-33: Include file (missingIncludeSystem) [information] 23-23: Include file (missingIncludeSystem) [information] 24-24: Include file (missingIncludeSystem) [information] 25-25: Include file (missingIncludeSystem) [information] 26-26: Include file (missingIncludeSystem) [information] 27-27: Include file (missingIncludeSystem) [information] 28-28: Include file (missingIncludeSystem) [information] 24-24: Include file (missingIncludeSystem) [information] 25-25: Include file (missingIncludeSystem) [information] 26-26: Include file (missingIncludeSystem) [information] 27-27: Include file (missingIncludeSystem) [information] 28-28: Include file (missingIncludeSystem) [information] 29-29: Include file (missingIncludeSystem) [information] 23-23: Include file (missingIncludeSystem) [information] 24-24: Include file (missingIncludeSystem) [information] 25-25: Include file (missingIncludeSystem) [information] 26-26: Include file (missingIncludeSystem) [information] 27-27: Include file (missingIncludeSystem) [information] 28-28: Include file (missingIncludeSystem) [information] 29-29: Include file (missingIncludeSystem) [information] 23-23: Include file (missingIncludeSystem) [information] 24-24: Include file (missingIncludeSystem) [information] 25-25: Include file (missingIncludeSystem) [information] 26-26: Include file (missingIncludeSystem) [information] 27-27: Include file (missingIncludeSystem) [information] 28-28: Include file (missingIncludeSystem) [information] 29-29: Include file (missingIncludeSystem) [information] 30-30: Include file (missingIncludeSystem) [information] 31-31: Include file (missingIncludeSystem) [information] 32-32: Include file (missingIncludeSystem) [information] 33-33: Include file (missingIncludeSystem) [information] 34-34: Include file (missingIncludeSystem) [information] 35-35: Include file (missingIncludeSystem) [information] 23-23: Include file (missingIncludeSystem) [information] 24-24: Include file (missingIncludeSystem) [information] 25-25: Include file (missingIncludeSystem) [information] 26-26: Include file (missingIncludeSystem) [information] 27-27: Include file (missingIncludeSystem) [information] 23-23: Include file (missingIncludeSystem) [information] 24-24: Include file (missingIncludeSystem) [information] 25-25: Include file (missingIncludeSystem) [information] 26-26: Include file (missingIncludeSystem) [information] 27-27: Include file (missingIncludeSystem) [information] 28-28: Include file (missingIncludeSystem) [information] 29-29: Include file (missingIncludeSystem) [information] 30-30: Include file (missingIncludeSystem) [information] 31-31: Include file (missingIncludeSystem) [information] 32-32: Include file (missingIncludeSystem) [style] 114-114: The function 'countNodesFromRoot' is never used. (unusedFunction) [style] 99-99: The function 'getNextControl' is never used. (unusedFunction) [style] 103-103: The function 'modeFromString' is never used. (unusedFunction) [style] 111-111: The function 'getSeed' is never used. (unusedFunction) [error] 260-260: Boolean value assigned to pointer. (assignBoolToPointer) [style] 208-208: The function 'getSimulationPath' is never used. (unusedFunction) ⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (15)
🔇 Additional comments (15)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In @.pre-commit-config.yaml:
- Line 134: The entry list currently defined as
"Numpy|Cmake|CCache|Github|PyTest|Mqt|Tum" should include "Nanobind" to catch
the common miscapitalization of "nanobind"; update the entry value (the "entry"
key) to insert the token Nanobind into the pipe-separated list so the
linter/pre-commit check flags incorrect casing.
In @bindings/bindings.cpp:
- Around line 240-264: The constructor binding copies
PathSimulator::Configuration by value; change the lambda signature in the first
__init__ overload to take const PathSimulator::Configuration& config (and update
the parameter name where used) to avoid an unnecessary copy when constructing
PathSimulator(std::move(qc), config); keep the default argument "config"_a =
PathSimulator::Configuration() as-is so pybind can still supply a default.
📜 Review details
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (10)
.clang-tidy.github/workflows/ci.yml.pre-commit-config.yamlCHANGELOG.mdCMakeLists.txtUPGRADING.mdbindings/CMakeLists.txtbindings/bindings.cppcmake/ExternalDependencies.cmakepyproject.toml
💤 Files with no reviewable changes (1)
- .clang-tidy
🧰 Additional context used
🧠 Learnings (24)
📓 Common learnings
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/dd/register_matrix_dds.cpp:64-109
Timestamp: 2025-12-15T01:54:22.129Z
Learning: In the munich-quantum-toolkit/core repository, after migrating to nanobind, docstrings for Python bindings are now added directly in the C++ binding code (using R"pb(...)pb" syntax) and stub files (.pyi) are auto-generated using the `bindings/generate-stubs.sh` script. This replaces the previous pybind11 approach where docstrings were manually maintained in stub files.
Learnt from: burgholzer
Repo: munich-quantum-toolkit/qcec PR: 817
File: pyproject.toml:81-82
Timestamp: 2026-01-09T17:58:10.350Z
Learning: In the Munich Quantum Toolkit projects using nanobind, setting `wheel.py-api = "cp312"` in `[tool.scikit-build]` enables Stable ABI wheels only for Python 3.12+ (where nanobind supports it), while automatically building regular non-ABI3 wheels for earlier Python versions (3.10, 3.11) and free-threading builds (3.14t). This allows a single configuration to appropriately handle both old and new Python versions without forcing incompatible ABI requirements.
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1246
File: pyproject.toml:340-341
Timestamp: 2025-10-09T22:15:59.924Z
Learning: Qiskit publishes ABI3 wheels (e.g., cp39-abi3) that are forward-compatible with newer Python versions including Python 3.14, so no explicit Python 3.14 wheels are required for qiskit to work on Python 3.14.
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1355
File: bindings/fomac/fomac.cpp:227-264
Timestamp: 2025-12-07T01:21:27.544Z
Learning: In the munich-quantum-toolkit/core repository, docstrings for Python bindings are added to the corresponding stub files (.pyi) rather than directly in the pybind11 C++ bindings code. This practice may change if the project adopts nanobind with automatic stub generation.
Learnt from: marcelwa
Repo: munich-quantum-toolkit/core PR: 1243
File: test/python/qdmi/qiskit/conftest.py:155-157
Timestamp: 2025-11-04T15:22:19.558Z
Learning: The munich-quantum-toolkit/core repository requires Python 3.10 or later, so Python 3.10+ features (such as `zip(..., strict=...)`, pattern matching, etc.) are acceptable and should not be flagged as compatibility issues.
Learnt from: denialhaag
Repo: munich-quantum-toolkit/debugger PR: 160
File: pyproject.toml:54-54
Timestamp: 2025-10-11T19:39:32.050Z
Learning: Qiskit packages use cp39-abi3 wheels (stable ABI) which are forward-compatible with Python 3.9+ including Python 3.14, even if the package classifiers don't explicitly list Python 3.14 support.
Learnt from: burgholzer
Repo: munich-quantum-toolkit/qmap PR: 862
File: pyproject.toml:65-66
Timestamp: 2025-12-13T20:08:45.549Z
Learning: In the qmap project (pyproject.toml), maintain broad compatibility with dependencies across supported Python versions. Avoid artificially raising minimum version requirements unless there's a specific need (e.g., to guarantee binary wheel availability for certain Python versions, or to access required features). The goal is to keep the software as broadly compatible as possible with the rest of the ecosystem.
📚 Learning: 2025-12-15T01:54:22.129Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/dd/register_matrix_dds.cpp:64-109
Timestamp: 2025-12-15T01:54:22.129Z
Learning: In the munich-quantum-toolkit/core repository, after migrating to nanobind, docstrings for Python bindings are now added directly in the C++ binding code (using R"pb(...)pb" syntax) and stub files (.pyi) are auto-generated using the `bindings/generate-stubs.sh` script. This replaces the previous pybind11 approach where docstrings were manually maintained in stub files.
Applied to files:
.github/workflows/ci.ymlCHANGELOG.mdpyproject.tomlbindings/bindings.cppbindings/CMakeLists.txtcmake/ExternalDependencies.cmake
📚 Learning: 2026-01-09T17:58:10.350Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/qcec PR: 817
File: pyproject.toml:81-82
Timestamp: 2026-01-09T17:58:10.350Z
Learning: In the Munich Quantum Toolkit projects using nanobind, setting `wheel.py-api = "cp312"` in `[tool.scikit-build]` enables Stable ABI wheels only for Python 3.12+ (where nanobind supports it), while automatically building regular non-ABI3 wheels for earlier Python versions (3.10, 3.11) and free-threading builds (3.14t). This allows a single configuration to appropriately handle both old and new Python versions without forcing incompatible ABI requirements.
Applied to files:
.github/workflows/ci.ymlUPGRADING.mdCHANGELOG.mdpyproject.tomlcmake/ExternalDependencies.cmake
📚 Learning: 2025-12-07T01:21:27.544Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1355
File: bindings/fomac/fomac.cpp:227-264
Timestamp: 2025-12-07T01:21:27.544Z
Learning: In the munich-quantum-toolkit/core repository, docstrings for Python bindings are added to the corresponding stub files (.pyi) rather than directly in the pybind11 C++ bindings code. This practice may change if the project adopts nanobind with automatic stub generation.
Applied to files:
.github/workflows/ci.ymlpyproject.tomlbindings/bindings.cppbindings/CMakeLists.txt
📚 Learning: 2025-12-14T16:51:52.504Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core-plugins-catalyst PR: 23
File: .readthedocs.yaml:13-18
Timestamp: 2025-12-14T16:51:52.504Z
Learning: In the munich-quantum-toolkit/core-plugins-catalyst repository, LLVM and MLIR toolchains are required for the documentation build because `uv run` includes a full build of the package, which compiles C++/MLIR extensions using scikit-build-core.
Applied to files:
.github/workflows/ci.ymlpyproject.toml
📚 Learning: 2025-10-09T22:15:59.924Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1246
File: pyproject.toml:340-341
Timestamp: 2025-10-09T22:15:59.924Z
Learning: Qiskit publishes ABI3 wheels (e.g., cp39-abi3) that are forward-compatible with newer Python versions including Python 3.14, so no explicit Python 3.14 wheels are required for qiskit to work on Python 3.14.
Applied to files:
UPGRADING.mdpyproject.toml
📚 Learning: 2025-12-05T17:45:37.602Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1360
File: .github/workflows/reusable-mlir-tests.yml:40-43
Timestamp: 2025-12-05T17:45:37.602Z
Learning: In the munich-quantum-toolkit/core repository, patch releases of LLVM dependencies don't require documentation updates, changelog entries, or additional tests beyond what's validated by passing CI checks.
Applied to files:
CHANGELOG.mdcmake/ExternalDependencies.cmake
📚 Learning: 2025-10-14T14:37:38.047Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/yaqs PR: 212
File: CHANGELOG.md:12-15
Timestamp: 2025-10-14T14:37:38.047Z
Learning: In the munich-quantum-toolkit/yaqs project, changelog entries follow the template: "- $TITLE ([#$NUMBER]($URL)) ([**AUTHOR**](https://github.com/$AUTHOR))". Issue references should not be included in changelog entries; the PR number is sufficient for traceability.
Applied to files:
CHANGELOG.md
📚 Learning: 2025-12-13T20:08:45.549Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/qmap PR: 862
File: pyproject.toml:65-66
Timestamp: 2025-12-13T20:08:45.549Z
Learning: In the qmap project (pyproject.toml), maintain broad compatibility with dependencies across supported Python versions. Avoid artificially raising minimum version requirements unless there's a specific need (e.g., to guarantee binary wheel availability for certain Python versions, or to access required features). The goal is to keep the software as broadly compatible as possible with the rest of the ecosystem.
Applied to files:
pyproject.toml
📚 Learning: 2025-10-10T08:09:54.528Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1246
File: bindings/CMakeLists.txt:0-0
Timestamp: 2025-10-10T08:09:54.528Z
Learning: In the Munich Quantum Toolkit (MQT) Core project, scikit-build-core is configured with `wheel.install-dir = "mqt/core"` in pyproject.toml, which automatically prefixes all CMake `DESTINATION` paths with `mqt/core/` during wheel installation. Therefore, CMake install destinations are relative to the `mqt/core` package namespace, not `site-packages`.
Applied to files:
pyproject.tomlbindings/CMakeLists.txtcmake/ExternalDependencies.cmake
📚 Learning: 2025-10-10T08:10:16.394Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1246
File: test/python/na/test_na_fomac.py:35-0
Timestamp: 2025-10-10T08:10:16.394Z
Learning: In the munich-quantum-toolkit/core repository, scikit-build-core is configured with `wheel.install-dir = "mqt/core"` in pyproject.toml, which means CMake `install()` commands with `DESTINATION <path>` install files relative to `mqt/core/` in the wheel, making them accessible via `files("mqt.core").joinpath("<path>")`.
Applied to files:
pyproject.tomlbindings/CMakeLists.txtcmake/ExternalDependencies.cmake
📚 Learning: 2025-12-28T17:13:36.900Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1403
File: pyproject.toml:98-102
Timestamp: 2025-12-28T17:13:36.900Z
Learning: In the munich-quantum-toolkit/core project, scikit-build-core is intelligent enough to skip build targets listed in pyproject.toml that don't exist for a given platform, so platform-specific targets (like `-dyn` targets conditioned on `NOT WIN32`) can be unconditionally listed in `build.targets` without causing Windows build failures.
Applied to files:
pyproject.toml
📚 Learning: 2025-12-15T01:59:17.023Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: python/mqt/core/ir/operations.pyi:9-16
Timestamp: 2025-12-15T01:59:17.023Z
Learning: In the munich-quantum-toolkit/core repository, stub files (.pyi) are auto-generated by nanobind's stubgen tool and should not be manually modified for style preferences, as changes would be overwritten during regeneration.
Applied to files:
pyproject.toml
📚 Learning: 2025-11-04T15:22:19.558Z
Learnt from: marcelwa
Repo: munich-quantum-toolkit/core PR: 1243
File: test/python/qdmi/qiskit/conftest.py:155-157
Timestamp: 2025-11-04T15:22:19.558Z
Learning: The munich-quantum-toolkit/core repository requires Python 3.10 or later, so Python 3.10+ features (such as `zip(..., strict=...)`, pattern matching, etc.) are acceptable and should not be flagged as compatibility issues.
Applied to files:
pyproject.toml
📚 Learning: 2025-11-04T14:26:25.420Z
Learnt from: marcelwa
Repo: munich-quantum-toolkit/core PR: 1243
File: test/python/qdmi/qiskit/conftest.py:11-19
Timestamp: 2025-11-04T14:26:25.420Z
Learning: In the munich-quantum-toolkit/core repository, Qiskit is always available as a dependency during testing, so import guards for qiskit-dependent imports in test files (e.g., test/python/qdmi/qiskit/*.py) are not necessary.
Applied to files:
pyproject.toml
📚 Learning: 2025-10-11T19:39:32.050Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/debugger PR: 160
File: pyproject.toml:54-54
Timestamp: 2025-10-11T19:39:32.050Z
Learning: Qiskit packages use cp39-abi3 wheels (stable ABI) which are forward-compatible with Python 3.9+ including Python 3.14, even if the package classifiers don't explicitly list Python 3.14 support.
Applied to files:
pyproject.toml
📚 Learning: 2025-12-19T00:05:54.428Z
Learnt from: denialhaag
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/fomac/fomac.cpp:111-116
Timestamp: 2025-12-19T00:05:54.428Z
Learning: In the munich-quantum-toolkit/core repository after migrating to nanobind, lifetime management differs from pybind11: `nb::keep_alive<nurse, patient>()` does not exist in nanobind. Instead, use `nb::rv_policy::reference_internal` when binding methods that return objects referencing internal state of the parent object (e.g., Session::getDevices returning Device objects that depend on the Session). This tells nanobind to keep the parent alive while children exist.
Applied to files:
bindings/bindings.cpp
📚 Learning: 2025-12-22T01:25:21.609Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/ir/register_permutation.cpp:153-171
Timestamp: 2025-12-22T01:25:21.609Z
Learning: In the munich-quantum-toolkit/core repository, when using nanobind iterator factory functions like `make_key_iterator` and `make_iterator`, the unqualified form (without explicit `nb::` prefix) is preferred. The clang-tidy configuration suggests removal of explicit namespace qualification, relying on ADL (Argument-Dependent Lookup) to resolve these functions correctly.
Applied to files:
bindings/bindings.cppbindings/CMakeLists.txt
📚 Learning: 2025-12-21T22:35:08.572Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1383
File: bindings/fomac/fomac.cpp:348-364
Timestamp: 2025-12-21T22:35:08.572Z
Learning: In the munich-quantum-toolkit/core repository's nanobind bindings, use `.sig("...")` on parameter arguments that have vector or container defaults (e.g., `"sites"_a.sig("...") = std::vector<fomac::Session::Device::Site>{}`) to prevent exposing mutable defaults in the Python API, which would be flagged as a code smell by Python linters. This pattern is preferred over removing `.sig("...")` even though it shows `...` in the stub signature.
Applied to files:
bindings/bindings.cppbindings/CMakeLists.txt
📚 Learning: 2025-12-28T17:14:53.890Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1403
File: src/qdmi/na/CMakeLists.txt:31-38
Timestamp: 2025-12-28T17:14:53.890Z
Learning: In the munich-quantum-toolkit/core repository, the NA device generator target (mqt-core-qdmi-na-device-gen) is intentionally propagated to MQT_CORE_TARGETS via list(APPEND) because it's publicly linked to the NA device library (the NA device uses a public function from the generator). The SC device generator is not propagated because it has no such dependency with the SC device library.
Applied to files:
bindings/CMakeLists.txtcmake/ExternalDependencies.cmake
📚 Learning: 2025-11-03T23:09:26.881Z
Learnt from: burgholzer
Repo: munich-quantum-toolkit/core PR: 1287
File: test/qdmi/dd/CMakeLists.txt:9-21
Timestamp: 2025-11-03T23:09:26.881Z
Learning: The CMake functions `generate_device_defs_executable` and `generate_prefixed_qdmi_headers` used in QDMI device test CMakeLists.txt files are provided by the external QDMI library (fetched via FetchContent from https://github.com/Munich-Quantum-Software-Stack/qdmi.git), specifically in the cmake/PrefixHandling.cmake module of the QDMI repository.
Applied to files:
cmake/ExternalDependencies.cmake
📚 Learning: 2025-12-01T11:00:40.342Z
Learnt from: flowerthrower
Repo: munich-quantum-toolkit/core-plugins-catalyst PR: 1
File: CHANGELOG.md:18-18
Timestamp: 2025-12-01T11:00:40.342Z
Learning: In the munich-quantum-toolkit/core-plugins-catalyst repository, the CHANGELOG.md intentionally references the parent MQT Core repository's release notes (https://github.com/munich-quantum-toolkit/core/releases) because the plugin repository is based on work performed in the parent repository.
Applied to files:
cmake/ExternalDependencies.cmake
📚 Learning: 2025-10-09T13:14:10.178Z
Learnt from: DRovara
Repo: munich-quantum-toolkit/core PR: 1108
File: mlir/lib/Dialect/MQTOpt/Transforms/ReplaceBasisStateControlsWithIfPattern.cpp:219-221
Timestamp: 2025-10-09T13:14:10.178Z
Learning: The MQT Core project (munich-quantum-toolkit/core repository) uses the C++20 standard, not C++17. C++20 features such as abbreviated function templates (e.g., `const auto&` parameters) are supported and valid in this codebase.
Applied to files:
cmake/ExternalDependencies.cmake
📚 Learning: 2025-12-05T15:57:39.701Z
Learnt from: flowerthrower
Repo: munich-quantum-toolkit/core-plugins-catalyst PR: 3
File: lib/Conversion/CatalystQuantumToMQTOpt/CMakeLists.txt:22-25
Timestamp: 2025-12-05T15:57:39.701Z
Learning: The munich-quantum-toolkit projects (core and core-plugins-catalyst) use `file(GLOB_RECURSE ...)` patterns in CMakeLists.txt files to collect header files, following an established convention in the parent repository for consistency across the codebase.
Applied to files:
cmake/ExternalDependencies.cmake
🧬 Code graph analysis (1)
bindings/bindings.cpp (1)
include/PathSimulator.hpp (9)
mode(103-121)mode(103-103)mode(123-138)mode(123-123)bracketSize(220-220)startingPoint(221-221)startingPoint(222-223)Configuration(95-101)Configuration(95-99)
🪛 Cppcheck (2.19.0)
bindings/bindings.cpp
[information] 23-23: Include file
(missingIncludeSystem)
[information] 24-24: Include file
(missingIncludeSystem)
[information] 25-25: Include file
(missingIncludeSystem)
[information] 26-26: Include file
(missingIncludeSystem)
[information] 27-27: Include file
(missingIncludeSystem)
[information] 28-28: Include file
(missingIncludeSystem)
[information] 29-29: Include file
(missingIncludeSystem)
[information] 30-30: Include file
(missingIncludeSystem)
[information] 31-31: Include file
(missingIncludeSystem)
[information] 32-32: Include file
(missingIncludeSystem)
[information] 33-33: Include file
(missingIncludeSystem)
[information] 23-23: Include file
(missingIncludeSystem)
[information] 24-24: Include file
(missingIncludeSystem)
[information] 25-25: Include file
(missingIncludeSystem)
[information] 26-26: Include file
(missingIncludeSystem)
[information] 27-27: Include file
(missingIncludeSystem)
[information] 28-28: Include file
(missingIncludeSystem)
[information] 24-24: Include file
(missingIncludeSystem)
[information] 25-25: Include file
(missingIncludeSystem)
[information] 26-26: Include file
(missingIncludeSystem)
[information] 27-27: Include file
(missingIncludeSystem)
[information] 28-28: Include file
(missingIncludeSystem)
[information] 29-29: Include file
(missingIncludeSystem)
[information] 23-23: Include file
(missingIncludeSystem)
[information] 24-24: Include file
(missingIncludeSystem)
[information] 25-25: Include file
(missingIncludeSystem)
[information] 26-26: Include file
(missingIncludeSystem)
[information] 27-27: Include file
(missingIncludeSystem)
[information] 28-28: Include file
(missingIncludeSystem)
[information] 29-29: Include file
(missingIncludeSystem)
[information] 23-23: Include file
(missingIncludeSystem)
[information] 24-24: Include file
(missingIncludeSystem)
[information] 25-25: Include file
(missingIncludeSystem)
[information] 26-26: Include file
(missingIncludeSystem)
[information] 27-27: Include file
(missingIncludeSystem)
[information] 28-28: Include file
(missingIncludeSystem)
[information] 29-29: Include file
(missingIncludeSystem)
[information] 30-30: Include file
(missingIncludeSystem)
[information] 31-31: Include file
(missingIncludeSystem)
[information] 32-32: Include file
(missingIncludeSystem)
[information] 33-33: Include file
(missingIncludeSystem)
[information] 34-34: Include file
(missingIncludeSystem)
[information] 35-35: Include file
(missingIncludeSystem)
[information] 23-23: Include file
(missingIncludeSystem)
[information] 24-24: Include file
(missingIncludeSystem)
[information] 25-25: Include file
(missingIncludeSystem)
[information] 26-26: Include file
(missingIncludeSystem)
[information] 27-27: Include file
(missingIncludeSystem)
[information] 23-23: Include file
(missingIncludeSystem)
[information] 24-24: Include file
(missingIncludeSystem)
[information] 25-25: Include file
(missingIncludeSystem)
[information] 26-26: Include file
(missingIncludeSystem)
[information] 27-27: Include file
(missingIncludeSystem)
[information] 28-28: Include file
(missingIncludeSystem)
[information] 29-29: Include file
(missingIncludeSystem)
[information] 30-30: Include file
(missingIncludeSystem)
[information] 31-31: Include file
(missingIncludeSystem)
[information] 32-32: Include file
(missingIncludeSystem)
[information] 33-33: Include file
(missingIncludeSystem)
[information] 34-34: Include file
(missingIncludeSystem)
[information] 35-35: Include file
(missingIncludeSystem)
[information] 36-36: Include file
(missingIncludeSystem)
[information] 37-37: Include file
(missingIncludeSystem)
[style] 114-114: The function 'countNodesFromRoot' is never used.
(unusedFunction)
[style] 99-99: The function 'getNextControl' is never used.
(unusedFunction)
[style] 103-103: The function 'modeFromString' is never used.
(unusedFunction)
[style] 111-111: The function 'getSeed' is never used.
(unusedFunction)
[error] 264-264: Boolean value assigned to pointer.
(assignBoolToPointer)
[performance] 243-243: Function parameter 'config' should be passed by const reference.
(passedByValue)
[style] 208-208: The function 'getSimulationPath' is never used.
(unusedFunction)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (15)
- GitHub Check: 🇨 Test 🍎 (macos-14, clang, Debug) / 🍎 macos-14 clang Debug
- GitHub Check: 🐍 Test (ubuntu-24.04) / 🐍 ubuntu-24.04
- GitHub Check: 🇨 Test 🍎 (macos-15-intel, clang, Release) / 🍎 macos-15-intel clang Release
- GitHub Check: 🐍 Test (ubuntu-24.04-arm) / 🐍 ubuntu-24.04-arm
- GitHub Check: 🐍 Test (macos-15-intel) / 🐍 macos-15-intel
- GitHub Check: 🇨 Test 🍎 (macos-14, clang, Release) / 🍎 macos-14 clang Release
- GitHub Check: 🐍 Test (windows-2022) / 🐍 windows-2022
- GitHub Check: 🇨 Test 🐧 (ubuntu-24.04, gcc, Debug) / 🐧 ubuntu-24.04 gcc Debug
- GitHub Check: 🇨 Test 🐧 (ubuntu-24.04, gcc, Release) / 🐧 ubuntu-24.04 gcc Release
- GitHub Check: 🇨 Test 🏁 (windows-2022, msvc, Release) / 🏁 windows-2022 msvc Release
- GitHub Check: 🇨 Test 🐧 (ubuntu-24.04-arm, gcc, Release) / 🐧 ubuntu-24.04-arm gcc Release
- GitHub Check: 🇨 Test 🏁 (windows-11-arm, msvc, Release) / 🏁 windows-11-arm msvc Release
- GitHub Check: 🇨 Test 🏁 (windows-2022, msvc, Debug) / 🏁 windows-2022 msvc Debug
- GitHub Check: 🇨 Lint / 🚨 Lint
- GitHub Check: 🇨 Coverage / 📈 Coverage
🔇 Additional comments (19)
CHANGELOG.md (1)
14-15: LGTM!The changelog entries clearly document the migration from pybind11 to nanobind and the introduction of Stable ABI wheels. The format follows the project's template with emoji prefixes, PR references, and author attribution.
UPGRADING.md (1)
7-24: LGTM!The upgrade documentation clearly explains the wheel distribution changes, provides proper rationale for the decisions, and correctly lists the remaining wheel variants. The distinction between removing 3.13t (experimental free-threading) while keeping 3.14t (stable free-threading) is accurately documented.
pyproject.toml (5)
10-14: LGTM!Build system requirements correctly updated to use nanobind and mqt.core 3.4.0. The version constraints are appropriate.
73-74: LGTM!The
wheel.py-api = "cp312"setting correctly enables Stable ABI wheels for Python 3.12+ while automatically falling back to regular wheels for earlier Python versions (3.10, 3.11) and free-threading builds. Based on learnings, this is the established pattern for MQT projects using nanobind.
299-303: LGTM!The shared library exclusions in
repair-wheel-commandare correctly updated to match the mqt-core 3.4.0 SOVERSION. This ensures the mqt-core shared libraries are not vendorized into the wheel, as they are provided by the mqt-core Python package.
51-51: LGTM!Runtime dependency on mqt.core correctly updated to version 3.4.0, consistent with the build-system requirements.
333-336: LGTM!The dependency-groups build section correctly mirrors the build-system requirements with nanobind and mqt.core 3.4.0.
.github/workflows/ci.yml (1)
153-153: LGTM!The cpp-linter job correctly installs nanobind instead of pybind11, with a pinned version for CI reproducibility. The version 2.10.2 matches the minimum version specified in pyproject.toml and is the latest available release.
CMakeLists.txt (1)
42-43: LGTM!Using
${SKBUILD_SABI_COMPONENT}is the correct approach for scikit-build-core integration. This variable automatically expands toDevelopment.SABIModulewhen building Stable ABI wheels (Python 3.12+) and remains empty for regular builds, providing seamless handling of both cases. Based on learnings, this pattern is consistent with other MQT projects using nanobind.cmake/ExternalDependencies.cmake (2)
28-32: LGTM!The nanobind detection pattern correctly mirrors the existing mqt-core detection approach. Setting
nanobind_ROOTvia the Python module's--cmake_diroutput ensures CMake finds the correct nanobind installation, andfind_package(nanobind CONFIG REQUIRED)properly enforces its presence.
36-41: LGTM!The MQT Core version bump to 3.4.0 aligns with the nanobind migration since MQT Core 3.4.0 provides the
add_mqt_python_binding_nanobindCMake function required by this PR.bindings/bindings.cpp (7)
23-40: LGTM!The nanobind includes and namespace setup are correctly configured. The STL type caster headers provide automatic conversion for the respective C++ types, and the
// NOLINT(misc-include-cleaner)comments appropriately suppress false positives from clang-tidy since these headers are used implicitly for type conversions.
45-74: LGTM!The
createSimulatortemplate function is correctly updated to use nanobind types (nb::class_<Sim>andnb::module_). The method bindings remain unchanged and are compatible with nanobind's API.
78-79: LGTM!The module declaration correctly uses
NB_MODULEmacro with the same module name macroMQT_DDSIM_MODULE_NAME. The import statement formqt.core.dduses the correct nanobind syntaxnb::module_::import_().
86-105: LGTM!The
__init__lambda with placementnewis the correct nanobind pattern for binding constructors that require custom initialization logic. The lambda receives a raw pointer to pre-allocated memory and constructs the object in-place. Based on learnings from the munich-quantum-toolkit/core repository, this pattern is the standard approach for nanobind bindings.
173-175: LGTM!The migration from
py::native_enumtonb::enum_is correct. nanobind's enum binding syntax is appropriate here.
219-236: LGTM!The
PathSimulator::Configurationbinding correctly uses:
nb::init()for default constructornb::def_rwfor read-write property bindings (replacingdef_readwrite)- Inline docstrings using
R"pbdoc(...)pbdoc"syntaxBased on learnings, after migrating to nanobind, docstrings are added directly in the C++ binding code and stub files are auto-generated.
267-298: LGTM!The
UnitarySimulatorModeenum binding andUnitarySimulatorconstructor binding follow the same correct nanobind patterns as the other simulators. The__init__lambda properly handles the optional seed parameter.bindings/CMakeLists.txt (1)
28-37: LGTM!The function rename to
add_mqt_python_binding_nanobindand removal ofpybind11_jsonfromLINK_LIBSare correct for the nanobind migration. nanobind provides its own STL bindings via headers like<nanobind/stl/map.h>which are included inbindings.cpp. Theadd_mqt_python_binding_nanobindfunction is provided by MQT Core 3.4.0 as required by the project.
burgholzer
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this looks really reasonable. I essentially just found one small thing besides the things that CodeRabbit already found.
Obviously, the code duplication for the constructor bindings is slightly unfortunate, but there isn't enough active development in this repository in my opinion to justify iterating further on this and I'd rather just rely on the solution that we have here.
Description
This PR fully replaces
pybind11withnanobind. This change will allow us to ship Stable ABI wheels, saving us PyPI space.Checklist:
I have added appropriate tests that cover the new/changed functionality.